#pragma once         // 头文件卫士，防止头文件被重复包含
#include <iostream>  // 标准输入输出流
#include <unistd.h>  // 包含 fork, getpid, read, write 等 POSIX 系统调用
#include <cstdint>   // 声明 uint32_t 等固定宽度整数类型
using namespace std; // 使用标准命名空间，避免频繁写 std::

// 函数指针类型定义
typedef void (*work_t)(int);        // 定义 work_t 类型为指向接受一个 int 参数并返回 void 的函数的指针
typedef void (*task_t)(int, pid_t); // 定义 task_t 类型为指向接受 int 和 pid_t 参数并返回 void 的函数的指针

// 打印日志任务函数：接收文件描述符和进程ID，输出日志信息
void PrintLog(int fd, pid_t pid)
{
    // 在子进程中执行，输出子进程ID, 文件描述符 (通常是 Socket FD 或其他资源 FD), 和任务描述
    cout << "sub process: " << pid << ",fd : " << fd << ", task is: pritnf log task\n"
         << endl;
}

// 重新加载配置任务函数：接收文件描述符和进程ID，输出重载配置信息
void ReloadConf(int fd, pid_t pid)
{
    // 在子进程中执行，模拟重载配置任务
    cout << "sub process: " << pid << ",fd : " << fd << ", task is: reload conf task\n"
         << endl;
}

// 连接MySQL任务函数：接收文件描述符和进程ID，输出数据库连接信息
void ConnectMysql(int fd, pid_t pid)
{
    // 在子进程中执行，模拟连接数据库任务
    cout << "sub process: " << pid << ",fd : " << fd << ", task is: connect mysql task\n"
         << endl;
}

// 任务函数指针数组：存储所有可执行的任务函数
task_t tasks[3] = {
    PrintLog,    // 索引0：打印日志任务函数 PrintLog 的地址
    ReloadConf,  // 索引1：重载配置任务函数 ReloadConf 的地址
    ConnectMysql // 索引2：连接MySQL任务函数 ConnectMysql 的地址
};

// 获取下一个任务的索引：随机返回0-2之间的整数，用于任务分发
uint32_t NextTask()
{
    return rand() % 3; // 使用 rand() 生成随机数，模 3 得到 0, 1 或 2
}

// 工作进程主函数：每个子进程都会执行这个函数
// 它负责从标准输入读取命令（任务码），并执行对应的任务函数
void worker(int fd) // 这里的 fd 似乎没有在 worker 函数内部直接使用，但作为参数传递进来了
{
    pid_t current_pid = getpid(); // 获取当前子进程的 PID

    while (true) // 进入无限循环，等待并处理任务
    {
        uint32_t command_code = 0; // 存储接收到的任务码
        // 从标准输入 (文件描述符 0) 读取一个 uint32_t 大小的命令码
        // 在 processpoll.cc 中，子进程会将管道的读端重定向到标准输入
        ssize_t n = read(0, &command_code, sizeof(command_code));

        if (n == sizeof(command_code)) // 如果成功读取到完整的 uint32_t 数据 (4 字节)
        {
            // 验证接收到的命令码是否有效 (0, 1, 或 2)
            if (command_code >= 3) // 如果命令码超出范围
            {
                // 无效命令，跳过本次处理，继续下一次循环等待新命令
                continue;
            }
            // 根据命令码，从 tasks 数组中找到对应的任务函数，并调用执行
            // 调用任务函数，传递文件描述符 fd 和当前子进程的 PID
            tasks[command_code](fd, current_pid);
        }
        else if (n == 0) // 如果 read 返回 0，表示读取到文件结束符 EOF
        {
            // 对于管道，read 返回 0 意味着管道的写端已经被全部关闭了
            // 这通常是父进程通过关闭写端来通知子进程退出
            cout << "sub process: " << current_pid << "quit now.." << endl;
            break; // 退出 while 循环，结束 worker 函数
        }
        // else if (n == -1) { /* 错误处理，如 EINTR 等 */ }
    }
    // worker 函数结束，子进程将在 main 函数中调用 exit(0) 退出
}